axios = require "axios"
dayjs = require "dayjs"
# Shortid = require "shortid"
{ customAlphabet } = require "nanoid/async"
nanoid = customAlphabet "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6
xml2js = require "xml2js"
db = require "../db"
util = require "util"
monk = require "monk"
_ = require "lodash"

objectIdWithTimestamp = (timestamp) ->
    if typeof timestamp is "string"
        timestamp = new Date timestamp
    hexSeconds = Math.floor(timestamp / 1000).toString 16
    constructedObjectId = monk.id hexSeconds + "0000000000000000"
    return constructedObjectId

module.exports =
    mongoToday: ->
        return
            $gt: objectIdWithTimestamp(
                dayjs()
                    .startOf "day"
                    .toDate()
            )
            $lt: objectIdWithTimestamp(
                dayjs()
                    .endOf "day"
                    .toDate()
            )
    mongoYestoday: ->
        return
            $gt: objectIdWithTimestamp(
                dayjs()
                    .add -1, "day"
                    .startOf "day"
                    .toDate()
            )
            $lt: objectIdWithTimestamp(
                dayjs()
                    .add -1, "day"
                    .endOf "day"
                    .toDate()
            )

    shortlink: (url) ->
        if process.env.SHORTLINK is "unuse"
            return url
        cached = await db.SHORTLINK.findOne url: url

        console.log cached
        return cached.short if cached

        unless process.env.SHORTLINK is "self"
            try
                { data } = await axios.post "http://w.qw360.cn", url: url

                if data.url
                    await db.SHORTLINK.insert
                        url: url
                        short: data.url
                    return data.url
                else
                    return url
            catch err
                console.log err
                return url
        else
            try
                shortid = await nanoid()
                console.log process.env.DOMAIN
                short = process.env.DOMAIN + "/w/" + shortid
                await db.SHORTLINK.insert
                    url: url
                    shortid: shortid
                    short: short
                return short
            catch err
                console.log err
                return url

    wepay: require "./wepay"
    send: require "./send"
    xml2js: (xml) ->
        return util.promisify(xml2js.parseString) xml, explicitArray: false, ignoreAttrs: true
    sleep: (ms) ->
        new Promise (res) ->
            setTimeout res, ms

    rsleep: ->
        new Promise (res) ->
            setTimeout res, _.random(0.2, 0.8) * 1000

    getUserId: (user) ->
        return user.id || user.contactid ||  new Date().getTime()
        # unless  user.headimgurl and  user.nickname
        #     return new Date().getTime()
        # try
        #     res = await axios.head user.headimgurl
        #     stamp = Math.round new Date(res.headers["last-modified"]).getTime() / 10000
        #     return Buffer.from("#{stamp}-#{user.nickname}", "utf-8").toString "base64"
        # catch err
        #     console.log err
        #     return new Date().getTime()

    sensitive: (str) ->
        return "" unless str
        hide = str.slice 3, -2
        stars = ""
        [0..hide.length].map ->
            stars += "*"
        return str.replace hide, stars

    getAccessToken: (refresh) ->
        fuwuhao = await db.SETTING.findOne id: "fuwuhao"
        if (
            fuwuhao?.access_token and
            fuwuhao.access_token_time >
                dayjs()
                    .add -1, "hours"
                    .toDate()
        )
            unless refresh
                return fuwuhao.access_token

        {
            data
        } =
            await axios.get(
                "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{
                    process.env.FUWUHAOID
                }&secret=#{process.env.FUWUHAOSECRET}"
            )
        console.log data
        await db.SETTING.findOneAndUpdate
            id: "fuwuhao"
        ,
            $set:
                access_token: data.access_token
                id: "fuwuhao"
                access_token_time: new Date()
        ,
            upsert: true

        return data.access_token

    getTicket: ->
        access_token = await module.exports.getAccessToken()

        fuwuhao = await db.SETTING.findOne id: "fuwuhao"

        if (
            fuwuhao?.ticket and
            fuwuhao.ticket_time >
                dayjs()
                    .add -1, "hours"
                    .toDate()
        )
            return fuwuhao.ticket
        {
            data
        } = await axios.get "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=#{access_token}&type=jsapi"
        if data.errcode is 40001
            access_token = await module.exports.getAccessToken true
            {
                data
            } =
                await axios.get(
                    "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=#{access_token}&type=jsapi"
                )

        await db.SETTING.findOneAndUpdate
            id: "fuwuhao"
        ,
            $set:
                ticket: data.ticket
                id: "fuwuhao"
                ticket_time: new Date()
        ,
            upsert: true

        return data.ticket
